using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using Jonathan.SharpDB;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;
using Jonathan.Tabber;

namespace Jonathan
{
	/// <summary>
	/// Jonathan's Main Form.
	/// </summary>
    public partial class frmMain : Form
    {
		/// <summary>
		/// Jonathan Application Options and saved data.
		/// </summary>
        private cJData m_ProgramData;

		/// <summary>
		/// List of Other Text's Chapters and Abbreveations.
		/// </summary>
		public static Dictionary<string, string> m_OtherTexts;

        #region - Constructor -

        /// <summary>
        /// Creates a new Main form...
        /// </summary>
        public frmMain()
        {
            InitializeComponent();

            // Load Last Configuration...
			m_OtherTexts = new Dictionary<string, string>();
            XmlSerializer ser = new XmlSerializer(typeof(cJData));
            using (StreamReader sr = new StreamReader(Common.DATA_FOLDER + Common.FILE_PROGRAM_DATA))
            {
                this.m_ProgramData = (cJData)ser.Deserialize(sr);
            }

            this.Location = this.m_ProgramData.Location;

            // Move if needed...
            int w = 0;
            foreach (Screen s in Screen.AllScreens)
                w += s.Bounds.Width;
            if (this.Location.X > w)
                this.Location = new Point(0, 0);

            this.WindowState = this.m_ProgramData.WindowState;
            if(this.WindowState != FormWindowState.Maximized)
                this.Size = this.m_ProgramData.Size;

            if (this.m_ProgramData.MouseOverToolTips)
                this._mnuToolShowTTMouseOver.Checked = true;
            else
                this._mnuToolShowTTClick.Checked = true;

            this._mnuAskToSave.Checked = this.m_ProgramData.AskSaveLayoutOnExit;
            this._mnuSaveOnExit.Checked = this.m_ProgramData.SaveLayoutOnExit;
            this._mnuToolShowVerseBorders.Checked = this.m_ProgramData.ReaderOptions.ShowBorder;
            this._mnuToolHighlightVerse.Checked = this.m_ProgramData.ReaderOptions.HighlightRows;
            this._mnuBookMarks.DropDown = new BookMarkDropDown(this);

            // Add Page Close Event...
            this.m_Tabber.BeforePageClose += new Tabber.PageAddEventHandler(m_Tabber_BeforePageClose);
            this.m_Tabber.TabPanelDoubleClick += new TabPanelDoubleClickHandler(m_Tabber_TabPanelDoubleClick);

            // Check all the databases...
            this.CheckData();

            // Load Available Bibles...
            this.LoadBibles();

            // Load Other Books...
            this.LoadOtherBooks();

            // Load Reference...
            this.LoadReference();

            // Load Book Marks...
            this.LoadBookMarks();

            if (!this.m_ProgramData.SaveLayoutOnExit)
            {
                // Add the Start Tab...
                this.m_Tabber.AddTab(this.GetStartTab());
            }
            else
            {
                // Load the Last Layout...
                CreateTabberPageDel del = CreateTab;
                if (!this.m_Tabber.LoadLayout(this.m_ProgramData.TabLayoutFile, del))
                    this.m_Tabber.AddTab(this.GetStartTab());
            }
        }

        #endregion

        #region - Properties -

        /// <summary>
        /// Gets the Main Data for the Program...
        /// </summary>
        public cJData ProgramData
        {
            get { return this.m_ProgramData; }
        }

        /// <summary>
        /// Gets the Path to the Default Bible...
        /// </summary>
        public string DefaultBibleFile
        {
            get
            {
                foreach (cJData.icDBInfo db in this.m_ProgramData.BibleDatabases)
                {
                    if (db.Name.Equals(this.m_ProgramData.DefaultBible))
                    {
                        return Common.DATA_FOLDER + db.Path;
                    }
                }

                return null;
            }
        }

        #endregion

        #region - Set Default Bible -

        /// <summary>
        /// Sets the Default Bible...
        /// </summary>
        /// <param name="sender">Menu Item</param>
        /// <param name="e">Events</param>
        private void SetDefaultBible(object sender, EventArgs e)
        {
            // Get Menu item...
            ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
            this.m_ProgramData.DefaultBible = tsmi.Text;

            ToolStripDropDownMenu tsddm = tsmi.Owner as ToolStripDropDownMenu;
            for (int a = 0; a < tsddm.Items.Count; a++)
            {
                ToolStripMenuItem t = (ToolStripMenuItem)tsddm.Items[a];
                t.Checked = false;
            }

            tsmi.Checked = true;
        }

        #endregion

        #region - Load Data -

        /// <summary>
        /// Creates a tab with the given properties...
        /// </summary>
        /// <param name="tabType">Type of Tab.</param>
        /// <param name="tabTitle">Title of Tab.</param>
        /// <param name="tabInfo">Additional Tab Info.</param>
        /// <returns>Created Tab.</returns>
        public TabberPage CreateTab (string tabType, string tabTitle, string tabInfo)
        {
            if (tabTitle.Equals("Start"))
            {
                return GetStartTab();
            }
            else if (tabType == typeof(ctrlReader).ToString())
            {
                string[] versions = tabInfo.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                ctrlReader reader = new ctrlReader(this, versions[0], versions[1]);
                if (versions.Length > 2)
                {
                    for (int a = 2; a < versions.Length; a++)
                    {
                        reader.AddVersion(versions[a], versions[++a]);
                    }
                }
                reader.LoadBookList(false);
                if (tabTitle.Contains("|"))
                {
                    string[] spInfo = tabTitle.Split('|');
                    if (reader.ReaderType == Common.TYPE_BIBLE)
                    {
                        reader.SelectPassages(cParser.Parse(spInfo[1].Trim()));
                    }
                    else if (reader.ReaderType == Common.TYPE_OTHER)
                    {
                        reader.SelectChapter(1, spInfo[1].Trim().Split(','));
                    }
                    else if (reader.ReaderType == Common.TYPE_REFERENCE)
                    {
                        reader.SelectRefWord(spInfo[1].Trim(), false);
                    }
                }
                return reader;
            }
            else if (tabType == typeof(ctrlSearch).ToString())
            {
                ctrlSearch search = new ctrlSearch(this, GetSearchType(tabInfo));
                if (tabTitle.Contains("|"))
                {
                    string[] spInfo = tabTitle.Split('|');
                    search.Search(spInfo[1].Trim());
                }
                return search;
            }
            else if (tabType == typeof(ctrlNote).ToString())
            {
                ctrlNote note = new ctrlNote();
                if (!string.IsNullOrEmpty(tabInfo))
                    note.OpenFile(tabInfo);

                return note;
            }
            return new TabberPage(tabTitle);
        }

        /// <summary>
        /// Gets the type of search...
        /// </summary>
        /// <param name="searchType">String version of SearchType</param>
        /// <returns>string</returns>
        public static string GetSearchType (string searchType)
        {
            switch (searchType)
            {
                case "Passage":
					return Common.TYPE_PASSAGE;
                case "Reference":
					return Common.TYPE_REFERENCE;
                case "Bilbe":
                default:
					return Common.TYPE_BIBLE;
            }
        }

        /// <summary>
        /// Checks for all the available databases...
        /// </summary>
        private void CheckData ()
        {
            DirectoryInfo dirInfo = new DirectoryInfo(Common.DATA_FOLDER);
            FileInfo[] files = dirInfo.GetFiles("*.db", SearchOption.TopDirectoryOnly);
            this.m_ProgramData.BibleDatabases.Clear();
            this.m_ProgramData.OtherDatabases.Clear();
            this.m_ProgramData.ReferenceDatabases.Clear();
            this.m_ProgramData.DailyDatabases.Clear();
            this.m_ProgramData.TSK.Name = "";
            this.m_ProgramData.TSK.Path = "";
            foreach (FileInfo file in files)
            {
                Database db = new Database(file.FullName);
                Query q = new Query(QueryType.SELECT, Common.TABLE_INFO);
                q.SELECT("Version");
				q.SELECT("Type");
				q.SELECT(Common.ABBREVIATION);
                db.RunQuery(q);
                // Make sure we have the desired information...
                if (q.Results != null && q.Results.Columns.Count == 3)
                {
                    cJData.icDBInfo dbI = new cJData.icDBInfo();
                    dbI.Name = q.Results.GetFieldString(0, 0);
                    dbI.Path = file.Name;
                    if (q.Results.GetFieldString(1, 0).Equals(Common.TYPE_BIBLE, StringComparison.CurrentCultureIgnoreCase))
                    {
                        this.m_ProgramData.BibleDatabases.Add(dbI);
                    }
                    else if (q.Results.GetFieldString(1, 0).Equals(Common.TYPE_OTHER, StringComparison.CurrentCultureIgnoreCase))
                    {
						Query qBook = new Query(QueryType.SELECT, Common.TABLE_BOOK_LIST);
						qBook.SELECT(Common.BOOK_NAME);
						db.RunQuery(qBook);

						for (int a = 0; a < qBook.RowsReturned; a++)
						{
							m_OtherTexts.Add(qBook.Results.GetFieldString(0, 0), q.Results.GetFieldString(2, 0));
						}
                        this.m_ProgramData.OtherDatabases.Add(dbI);
                    }
                    else if (q.Results.GetFieldString(1, 0).Equals(Common.TYPE_REFERENCE, StringComparison.CurrentCultureIgnoreCase))
                    {
                        this.m_ProgramData.ReferenceDatabases.Add(dbI);
                    }
                    else if (q.Results.GetFieldString(1, 0).Equals(Common.TYPE_DAILY, StringComparison.CurrentCultureIgnoreCase))
                    {
                        this.m_ProgramData.DailyDatabases.Add(dbI);
                    }
                    else 
                    {
                        if (q.Results.GetFieldString(1, 0).Equals("tsk", StringComparison.CurrentCultureIgnoreCase))
                        {
                            this.m_ProgramData.TSK = dbI;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Loads the list of bibles...
        /// </summary>
        private void LoadBibles ()
        {
            // Get Results, create menus...
            foreach (cJData.icDBInfo db in this.m_ProgramData.BibleDatabases)
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem(db.Name);
                ToolStripMenuItem tsmid = new ToolStripMenuItem(db.Name);

                tsmi.Tag = Common.DATA_FOLDER + db.Path;
                tsmid.Tag = Common.DATA_FOLDER + db.Path;

                if (tsmid.Text == this.m_ProgramData.DefaultBible)
                {
                    tsmid.Checked = true;
                }

                this.m_mnuBibles.DropDownItems.Add(tsmi);
                this.m_mnuToolsDefaultBible.DropDownItems.Add(tsmid);

                tsmi.Click += new EventHandler(mnuBible_Click);
                tsmid.Click += new EventHandler(SetDefaultBible);
            }

            if (this.m_mnuBibles.DropDownItems.Count == 0)
            {
                this.m_mnuBibles.Visible = false;
            }
        }

        /// <summary>
        /// Loads the list of Other Books...
        /// </summary>
        private void LoadOtherBooks ()
        {
            // Get Results, create menus...
            foreach (cJData.icDBInfo db in this.m_ProgramData.OtherDatabases)
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem(db.Name);

                tsmi.Tag = Common.DATA_FOLDER + db.Path;
                this.m_mnuOtherBooks.DropDownItems.Add(tsmi);
                tsmi.Click += new EventHandler(mnuBible_Click);
            }

            if (this.m_mnuOtherBooks.DropDownItems.Count == 0)
            {
                this.m_mnuOtherBooks.Visible = false;
            }
        }

        /// <summary>
        /// Loads the list of Reference books...
        /// </summary>
        private void LoadReference ()
        {
            // Get Results, create menus...
            foreach (cJData.icDBInfo db in this.m_ProgramData.ReferenceDatabases)
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem(db.Name);

                tsmi.Tag = Common.DATA_FOLDER + db.Path;
                this.m_mnuReference.DropDownItems.Add(tsmi);
                tsmi.Click += new EventHandler(mnuBible_Click);
            }

            if (this.m_mnuReference.DropDownItems.Count == 0)
            {
                this.m_mnuReference.Visible = false;
            }
            else
            {
                this.m_mnuReference.DropDownItems.Add(new ToolStripSeparator());
                ToolStripMenuItem tsmiSearch = new ToolStripMenuItem("Search Reference");
                tsmiSearch.Click += new EventHandler(RefSearch_Click);
                this.m_mnuReference.DropDownItems.Add(tsmiSearch);
            }
        }

        /// <summary>
        /// Loads the list of BookMarks...
        /// </summary>
        private void LoadBookMarks ()
        {
            ((BookMarkDropDown)this._mnuBookMarks.DropDown).BookMarkControl.ClearGrid();
            foreach (cPassage bm in this.m_ProgramData.BookMarks)
            {
                // Add Book Mark...
                ((BookMarkDropDown)this._mnuBookMarks.DropDown).BookMarkControl.AddBookMark(bm);
            }
            ((BookMarkDropDown)this._mnuBookMarks.DropDown).BookMarkControl.SortGrid();
        }

        #endregion

        #region - Bible Click -

        /// <summary>
        /// Start a new Bible...
        /// </summary>
        /// <param name="sender">Menu Item</param>
        /// <param name="e">Events</param>
        private void mnuBible_Click(object sender, EventArgs e)
        {
            // Get the menu item...
            ToolStripMenuItem tsmi = sender as ToolStripMenuItem;

            // Add the Page to the main TabberGroup...
            this.m_Tabber.AddTab(new ctrlReader(this, tsmi.Text, tsmi.Tag.ToString()));
        }

        /// <summary>
        /// Loads a bible...
        /// </summary>
        /// <param name="version">Version to load.</param>
        /// <param name="book">Book to Start.</param>
        /// <param name="chapter">Chapter to go to.</param>
        /// <param name="verse">verse to highlight.</param>
        public void StartBible (List<cPassage> passages, TabberPage tp)//string book, string chapter, string verse)
        {
            if (passages != null && passages.Count > 0)
            {
                string path = this.GetDBPath(passages[0].Version);
                if (!string.IsNullOrEmpty(path))
                {
                    ctrlReader reader = new ctrlReader(this, passages[0].Version, path);
                    if (passages != null)//if (!string.IsNullOrEmpty(book) && !string.IsNullOrEmpty(chapter))
                    {
                        reader.LoadBookList(false);
                        reader.SelectPassages(passages);
                    }
                    if (tp == null)
                        this.m_Tabber.AddTab(reader);
                    else
                        this.m_Tabber.AddTab(reader, tp.Group);
                }
            }
        }

        /// <summary>
        /// Loads a reference...
        /// </summary>
        /// <param name="version">Version to Load.</param>
        /// <param name="word">Word to Lookup.</param>
        public void StartReference (string version, string word, TabberPage tp)
        {
            string path = "";
            foreach (cJData.icDBInfo dbi in this.m_ProgramData.ReferenceDatabases)
            {
                if (dbi.Name.Equals(version))
                {
                    path = Common.DATA_FOLDER + dbi.Path;
                    break;
                }
            }
            if (!string.IsNullOrEmpty(path))
            {
                ctrlReader reader = new ctrlReader(this, version, path);
                reader.SelectRefWord(word, false);
                if (tp == null)
                    this.m_Tabber.AddTab(reader);
                else
                    this.m_Tabber.AddTab(reader, tp.Group);
            }
        }

        /// <summary>
        /// Loads a reference...
        /// </summary>
        /// <param name="version">Version to Load.</param>
        /// <param name="words">Words to Lookup.</param>
        public void StartReference (string version, string[] words, TabberPage tp)
        {
            string path = "";
            foreach (cJData.icDBInfo dbi in this.m_ProgramData.ReferenceDatabases)
            {
                if (dbi.Name.Equals(version))
                {
                    path = Common.DATA_FOLDER + dbi.Path;
                    break;
                }
            }
            if (!string.IsNullOrEmpty(path))
            {
                ctrlReader reader = new ctrlReader(this, version, path);
                reader.SelectRefWords(words);
                if (tp == null)
                    this.m_Tabber.AddTab(reader);
                else
                    this.m_Tabber.AddTab(reader, tp.Group);
            }
        }

        #endregion

        #region - Get Start Tab -

        /// <summary>
        /// Adds a Start Tab to the main Tabber...
        /// </summary>
        private TabberPage GetStartTab ()
        {
            // Create a new TabberPage...
            Tabber.TabberPage page = new Tabber.TabberPage("Start");
            page.ShowCloseButton = false;

            // Add a new Start Control...
            page.Controls.Add(new ctrlStart(this));

            // Add the Page to the main TabberGroup...
            //this.m_Tabber.AddTab(page);
            return page;
        }

        #endregion

        #region - Menu Items -

        /// <summary>
        /// Closes the Application
        /// </summary>
        /// <param name="sender">Exit menu items</param>
        /// <param name="e">Events</param>
        private void m_mnuFileExit_Click(object sender, EventArgs e)
        {
            // Close this application...
            this.Close();
        }

        /// <summary>
        /// Option to Save On exit...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuSaveOnExit_Click (object sender, EventArgs e)
        {
            this.m_ProgramData.SaveLayoutOnExit = this._mnuSaveOnExit.Checked;
        }

        /// <summary>
        /// Option to ask to save on exit...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuAskToSave_Click (object sender, EventArgs e)
        {
            this.m_ProgramData.AskSaveLayoutOnExit = this._mnuAskToSave.Checked;
        }

        /// <summary>
        /// Creates a new Note Control...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuToolNote_Click (object sender, EventArgs e)
        {
            ctrlNote note = new ctrlNote();
            this.m_Tabber.AddTab(note);
        }

        /// <summary>
        /// Opens a new Note Tab...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void openNoteToolStripMenuItem_Click (object sender, EventArgs e)
        {
            if (this._ofdMain.ShowDialog() == DialogResult.OK)
            {
                FileInfo fi = new FileInfo(this._ofdMain.FileName);
                this._ofdMain.InitialDirectory = fi.Directory.FullName;
                ctrlNote note = new ctrlNote();
                note.OpenFile(fi.FullName);
                this.m_Tabber.AddTab(note);
            }
        }

        /// <summary>
        /// Closes all of the open tabs...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuFileCloseAllTabs_Click (object sender, EventArgs e)
        {
            for (int a = this.m_Tabber.TabGroups.Count - 1; a >= 0; a--)
            {
                if (this.m_Tabber.TabGroups[a].ContainsTab("Start"))
                {
                    for (int b = this.m_Tabber.TabGroups[a].TabButtons.Count - 1; b >= 0; b--)
                    {
                        ((Tabber.TabButton)this.m_Tabber.TabGroups[a].TabButtons[b]).Page.ClosePage();
                    }
                }
                else
                {
                    this.m_Tabber.TabGroups[a].CloseGroup();
                }
            }
        }

        /// <summary>
        /// Shows the About Form...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">EventArgs</param>
        private void aboutToolStripMenuItem_Click (object sender, EventArgs e)
        {
            frmAbout frm = new frmAbout();
            frm.ShowDialog(this);
        }

        /// <summary>
        /// Shows or Hides Borders around verses...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">EventArgs</param>
        private void _mnuToolShowVerseBorders_Click (object sender, EventArgs e)
        {
            this.m_ProgramData.ReaderOptions.ShowBorder = !this.m_ProgramData.ReaderOptions.ShowBorder;
            this.UpdateTabs(true, true, false);
        }

        /// <summary>
        /// Highlightes rows on mouse over...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">EventArgs</param>
        private void _mnuToolHighlightVerse_Click (object sender, EventArgs e)
        {
            this.m_ProgramData.ReaderOptions.HighlightRows = !this.m_ProgramData.ReaderOptions.HighlightRows;
            this.UpdateTabs(true, false, false);
        }

        /// <summary>
        /// Tool Tips will be shown on click...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuToolShowTTClick_Click (object sender, EventArgs e)
        {
            this._mnuToolShowTTMouseOver.Checked = false;
            this.m_ProgramData.MouseOverToolTips = false;
        }

        /// <summary>
        /// Tool Tips will be shown on mouse over...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuToolShowTTMouseOver_Click (object sender, EventArgs e)
        {
            this._mnuToolShowTTClick.Checked = false;
            this.m_ProgramData.MouseOverToolTips = true;
        }

        /// <summary>
        /// Opens the default bible...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void _mnuRead_Click (object sender, EventArgs e)
        {
            // Add the Page to the main TabberGroup...
            this.m_Tabber.AddTab(new ctrlReader(this, this.m_ProgramData.DefaultBible, this.DefaultBibleFile));
        }

        /// <summary>
        /// Changes the program font...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void m_mnuToolFont_Click (object sender, EventArgs e)
        {
            this.m_FontDlg.Font = this.m_ProgramData.DefaultFont.ToFont();
            if (this.m_FontDlg.ShowDialog() == DialogResult.OK)
            {
                this.m_ProgramData.DefaultFont = new cJData.SFont(this.m_FontDlg.Font);
                this.UpdateTabs(true, true, true);
            }
		}

		/// <summary>
		/// Occurs when the help tool menu item is clicked.
		/// </summary>
		/// <param name="sender">ToolStripMenuItem</param>
		/// <param name="e">EventArgs</param>
		private void helpToolStripMenuItem1_Click (object sender, EventArgs e)
		{
			if (File.Exists(Common.DATA_FOLDER + Common.HELP_FILE))
				System.Diagnostics.Process.Start(Common.DATA_FOLDER + Common.HELP_FILE);
			else
				MessageBox.Show(this, "Help file is missing!", "Jonathan", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}

		/// <summary>
		/// Occurs when the users click the SharpDB Viewer Menu Item in the Tools Menu.
		/// </summary>
		/// <param name="sender">ToolStripMenuItem (_mnuToolSharpDBViewer)</param>
		/// <param name="e">EventArgs</param>
		private void _mnuToolsSharpDBViewer_Click (object sender, EventArgs e)
		{
			SharpDB.fSharpDBViewer dbViewer = new fSharpDBViewer();
			dbViewer.Show(this);
		}

        #endregion

        #region - Before Page Close -

        /// <summary>
        /// Catches page close events for Tabber...
        /// </summary>
        /// <param name="pe">Page Event Args</param>
        private void m_Tabber_BeforePageClose (Tabber.PageEventArgs pe)
        {
            if (pe.Page.TabTitle == "Start")
            {
                pe.Cancel = true;
            }
        }

        #endregion

        #region - Get HTML Header -

		/// <summary>
		/// Gets the Starting string of html to put in all documents.
		/// </summary>
		/// <returns>string of html up to the body start tag</returns>
        public string GetHtmlHeader()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            sb.Append("<html><head><title>Jonathan</title>");
            sb.Append("<style type=\"text/css\">");

            sb.Append("A:link {text-decoration: underline; color: " + ColorTranslator.ToHtml(Color.DarkRed) + "; }");
            sb.Append("A:visited {text-decoration: underline; color: " + ColorTranslator.ToHtml(Color.DarkRed) + "; }");
            sb.Append("A:active {text-decoration: underline; color: " + ColorTranslator.ToHtml(Color.DarkRed) + "; }");
            sb.Append("A:hover {text-decoration: underline overline; color:  " + ColorTranslator.ToHtml(Color.DarkRed) + "; }");

            sb.Append("table { border: 1px solid #D4E0EE; border-collapse: collapse; font-family: \"" +
                this.m_ProgramData.DefaultFont.Name + "\", Arial, sans-serif; color: Black; font-size:" +
                Convert.ToString(this.m_ProgramData.DefaultFont.Size + 4) + ";}");
            sb.Append("th, td { border: " + ((this.m_ProgramData.ReaderOptions.ShowBorder) ? 1 : 0) + "px solid #D4E0EE; border-collapse: collapse; font-family: \"" +
                this.m_ProgramData.DefaultFont.Name + "\", Arial, sans-serif; color: Black; font-size:" +
                Convert.ToString(this.m_ProgramData.DefaultFont.Size + 4) + "; }");

            sb.Append("caption { font-size: 150%; font-weight: bold; margin: 5px;}");
            sb.Append("td, th { padding: 4px;}");
            sb.Append("td.passage { color: " + ColorTranslator.ToHtml(Color.DarkRed) + "; font-weight:bold;}");
            sb.Append("thead th { text-align: center; background: #FCFDFE; color: Black; font-size: 100% !important;}");
            sb.Append("tbody th {font-weight: bold;}");
			sb.Append("tbody tr { background: #FCFDFE; }");
			sb.Append(".normalRow { background: #FCFDFE; }");
			sb.Append(".goto {text-decoration: underline; color: " + ColorTranslator.ToHtml(Color.DarkRed) + "; }");

            if(this.m_ProgramData.ReaderOptions.HighlightRows)
                sb.Append(".highliteRow { background: yellow; }");
            else
                sb.Append(".highliteRow { background: #FCFDFE; }");

            sb.Append("table.search { cursor: default; }");
            sb.Append("tfoot th, tfoot td { font-size: 85%; }");

            sb.Append("#reader { border: 1px solid gray; width: 450px; position: absolute; left: 0px; top: 0px; background: #FCFDFE;}");
            sb.Append("#readerTitles { border: 1px solid gray; background: #FCFDFE;}");
            sb.Append("#innerReader { height: 500px; overflow: auto;}");

            sb.Append("</style>");

            sb.Append("<script type=\"text/javascript\">");

            // Resize...
            sb.Append("function resizeJonathan()");
            sb.Append("{");
            sb.Append("var theWidth, theHeight;");
            sb.Append("if (window.innerWidth)");
            sb.Append("{");
            sb.Append("theWidth = window.innerWidth;");
            sb.Append("}");
            sb.Append("else if (document.documentElement && document.documentElement.clientWidth)");
            sb.Append("{");
            sb.Append("theWidth = document.documentElement.clientWidth;");
            sb.Append("}");
            sb.Append("else if (document.body)");
            sb.Append("{");
            sb.Append("theWidth = document.body.clientWidth;");
            sb.Append("}");
            sb.Append("if (window.innerHeight)");
            sb.Append("{");
            sb.Append("theHeight = window.innerHeight;");
            sb.Append("}");
            sb.Append("else if (document.documentElement && document.documentElement.clientHeight)");
            sb.Append("{");
            sb.Append("theHeight = document.documentElement.clientHeight;");
            sb.Append("}");
            sb.Append("else if (document.body)");
            sb.Append("{");
            sb.Append("theHeight = document.body.clientHeight;");
            sb.Append("}");
            sb.Append("var read = document.getElementById('reader');");
            sb.Append("var readTitles = document.getElementById('readerTitles');");
            sb.Append("var innerRead = document.getElementById('innerReader');");
            sb.Append("if (read != null){");
            sb.Append("innerRead.style.height = theHeight - readTitles.offsetHeight;");
            sb.Append("innerRead.style.width = theWidth;");
            sb.Append("read.style.width = theWidth;");
            sb.Append("readTitles.style.width = theWidth;");
            sb.Append("}");
			sb.Append("}");

			sb.Append("function getTextSelection()");
			sb.Append("{");
			sb.Append("var tRange = document.selection.createRange();");
			sb.Append("var txt = tRange.text;");
			sb.Append("return txt;");
			sb.Append("}");

			sb.Append("function expandSelection()");
			sb.Append("{");
			sb.Append("var x = window.event.clientX;");
			sb.Append("var y = window.event.clientY;");
			sb.Append("var tRange = document.selection.createRange();");
			sb.Append("tRange.collapse();");
			sb.Append("tRange.moveToPoint(x, y);");
			sb.Append("tRange.expand('word');");
			sb.Append("tRange.select();");
			//sb.Append("return tRange.text;");
			sb.Append("}");

			sb.Append("var tRange = null;");
			sb.Append("function findString(strToFind)");
			sb.Append("{");
			sb.Append("var strFound;");
			sb.Append("if (tRange != null)");
			sb.Append("{");
			sb.Append("tRange.collapse(false);");
			sb.Append("strFound = tRange.findText(strToFind);");
			sb.Append("if (strFound) tRange.select();");
			sb.Append("}");
			sb.Append("if (tRange == null || strFound == 0)");
			sb.Append("{");
			sb.Append("tRange = document.body.createTextRange();");
			sb.Append("strFound = tRange.findText(strToFind);");
			sb.Append("if (strFound) tRange.select();");
			sb.Append("}");
			sb.Append("}");

            sb.Append("window.onresize = resizeJonathan;");
            sb.Append("</script>");

            sb.Append("</head><body onload=\"resizeJonathan();\" style=\" background: White; color: Black; font-family: \"" +
                this.Font.Name + "\", Arial, sans-serif; font-size:" + Convert.ToString(this.Font.Size + 4) + ";\">");

            return sb.ToString();
        }

        #endregion

        #region - Search -

        /// <summary>
        /// Starts a search...
        /// </summary>
        /// <param name="sender">Button</param>
        /// <param name="e">Events</param>
        private void m_btnSearch_Click(object sender, EventArgs e)
        {
            this.Search(this.m_txtSearch.Text);
        }

        /// <summary>
        /// Starts a search...
        /// </summary>
        /// <param name="sender">TextBox</param>
        /// <param name="e">Key Events</param>
        private void m_txtSearch_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.Search(this.m_txtSearch.Text);
            }
        }

        /// <summary>
        /// Creates a new search control, and searches for the given text...
        /// </summary>
        /// <param name="text"></param>
        public void Search(string text)
        {
            // Create a search control...
            ctrlSearch sControl = new ctrlSearch(this, Common.TYPE_BIBLE);

            // Add the Page to the main TabberGroup...
            this.m_Tabber.AddTab(sControl);

            if (text.Trim() != string.Empty)
            {
                sControl.Search(text);
            }
        }

        /// <summary>
        /// Creates a new search control, and searches for the given text...
        /// </summary>
        /// <param name="text">Text to lookup.</param>
        /// <param name="type">Type of Search.</param>
        /// <param name="oldpage">TabberPage request is comming from.</param>
        public void Search (string text, TabberPage oldpage, string type)
        {
            // Create a search control...
            ctrlSearch sControl = new ctrlSearch(this, type);

            // Add the Page to the main TabberGroup...
            this.m_Tabber.AddTab(oldpage.Group, sControl, Jonathan.Tabber.Tabber.TabDockStyle.Right);

            if (text.Trim() != string.Empty)
            {
                sControl.Search(text);
            }
        }

        /// <summary>
        /// Creates a new search control, and searches for the given text...
        /// </summary>
        /// <param name="version">Bible Version to Look in.</param>
        /// <param name="text">Text to lookup.</param>
        /// <param name="oldpage">TabberPage request is comming from.</param>
        public void Search (string version, string text, TabberPage oldpage)
        {
            // Create a search control...
            ctrlSearch sControl = new ctrlSearch(this, Common.TYPE_BIBLE);
            sControl.ChangeVersion(version);

            // Add the Page to the main TabberGroup...
            this.m_Tabber.AddTab(oldpage.Group, sControl, Jonathan.Tabber.Tabber.TabDockStyle.Right);

            if (text.Trim() != string.Empty)
            {
                sControl.Search(text);
            }
        }

        /// <summary>
        /// Creates a Search Control...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void searchToolStripMenuItem_Click (object sender, EventArgs e)
        {
            // Create a search control...
            ctrlSearch sControl = new ctrlSearch(this, Common.TYPE_BIBLE);

            // Add the Page to the main TabberGroup...
            this.m_Tabber.AddTab(sControl);
        }

        #endregion

        #region - Closing -

        /// <summary>
        /// Occurs before closing...
        /// </summary>
        /// <param name="e">Closing Events</param>
        protected override void OnClosing (CancelEventArgs e)
        {
            // Ask About Saving Tabber Layout...
            if (this.m_ProgramData.AskSaveLayoutOnExit)
            {
                frmExit exit = new frmExit(this);
                if (exit.ShowDialog(this) == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }

            if (!e.Cancel)
            {
                // We can empty these, because we re-check on startup...
                this.m_ProgramData.ReferenceDatabases.Clear();
                this.m_ProgramData.OtherDatabases.Clear();
                this.m_ProgramData.BibleDatabases.Clear();
                this.m_ProgramData.DailyDatabases.Clear();

                // Save some data...
                this.m_ProgramData.Size = this.Size;
                this.m_ProgramData.Location = this.Location;
                this.m_ProgramData.WindowState = this.WindowState;

                // Save Tabber Layout...
                try
                {
                    if (File.Exists(this.m_ProgramData.TabLayoutFile))
                        File.Delete(this.m_ProgramData.TabLayoutFile);
                    this.m_ProgramData.TabLayoutFile = "";

                    if (this.m_ProgramData.SaveLayoutOnExit)
                    {
                        this.m_ProgramData.TabLayoutFile = Common.DATA_FOLDER + Path.GetRandomFileName();
                        this.m_Tabber.SaveLayout(this.m_ProgramData.TabLayoutFile);
                    }
                }
                catch (IOException ex)
                {
                    Console.WriteLine(ex.Message);
                }

                using (StreamWriter sr = new StreamWriter(Common.DATA_FOLDER + Common.FILE_PROGRAM_DATA))
                {
                    XmlSerializer ser = new XmlSerializer(typeof(cJData));
                    ser.Serialize(sr, this.m_ProgramData);
                }
            }

            base.OnClosing(e);
        }

        #endregion

        #region - Passage Finder -

        /// <summary>
        /// Starts the Passage Finder with the given passages...
        /// </summary>
        /// <param name="sender">ToolStripButton</param>
        /// <param name="e">Events</param>
        private void m_btnFindPassage_Click (object sender, EventArgs e)
        {
            ctrlSearch search = new ctrlSearch(this, Common.TYPE_PASSAGE);
            if (!string.IsNullOrEmpty(this.m_txtJump.Text.Trim()))
            {
                search.Search(this.m_txtJump.Text.Trim());
            }
            this.m_Tabber.AddTab(search);
        }

        /// <summary>
        /// Starts the Passage Finder with the given passages...
        /// </summary>
        /// <param name="sender">TextBox</param>
        /// <param name="e">Events</param>
        void FindPassages_KeyDown (object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                this.m_btnFindPassage_Click(sender, null);
        }

        /// <summary>
        /// Starts the Passage Finder...
        /// </summary>
        /// <param name="sender">ToolStripMenuItem</param>
        /// <param name="e">Events</param>
        private void m_mnuToolsPassageFinder_Click (object sender, EventArgs e)
        {
            ctrlSearch search = new ctrlSearch(this, Common.TYPE_PASSAGE);
            this.m_Tabber.AddTab(search);
        }

        #endregion

        #region - Reference Lookup -

        /// <summary>
        /// Looksup the reference text...
        /// </summary>
        /// <param name="sender">ToolStripButton</param>
        /// <param name="e">Events</param>
        private void m_btnLookupGo_Click (object sender, EventArgs e)
        {
            ctrlSearch search = new ctrlSearch(this, Common.TYPE_REFERENCE);
            this.m_Tabber.AddTab(search);

            if (!string.IsNullOrEmpty(this.m_txtLookup.Text.Trim()))
            {
                search.Search(this.m_txtLookup.Text);
            }
        }

        /// <summary>
        /// Check for enter pressed in Reference lookup text box...
        /// </summary>
        /// <param name="sender">ToolStripTextBox</param>
        /// <param name="e">Events</param>
        void TxtLookUp_KeyDown (object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                this.m_btnLookupGo_Click(sender, null);
        }

        /// <summary>
        /// Opens the Reference Search...
        /// </summary>
        /// <param name="sender">ToolStripMenuItesm</param>
        /// <param name="e">Events</param>
        void RefSearch_Click (object sender, EventArgs e)
        {
            ctrlSearch search = new ctrlSearch(this, Common.TYPE_REFERENCE);
            this.m_Tabber.AddTab(search);
        }

        #endregion

        #region - Misc -

        /// <summary>
        /// Update the tabs...
        /// </summary>
        /// <param name="reader">Update Readers or Not</param>
        /// <param name="search">Update searches or Not</param>
        /// <param name="start">Update start or Not</param>
        private void UpdateTabs (bool reader, bool search, bool start)
        {
            foreach (TabberGroup tg in this.m_Tabber.TabGroups)
            {
                foreach (TabButton btn in tg.TabButtons)
                {
                    if (btn.Page.GetType() == typeof(ctrlReader) && reader)
                    {
                        ((ctrlReader)btn.Page).UpdateText();
                    }
                    else if (btn.Page.GetType() == typeof(ctrlSearch) && search)
                    {
                        ((ctrlSearch)btn.Page).UpdateFont();
                    }
                    else if (btn.ButtonText.Equals("Start") && start)
                    {
                        ((ctrlStart)btn.Page.Controls[0]).UpdateFont();
                    }
                }
            }
        }

        /// <summary>
        /// Gets the Path to the given datbase..
        /// </summary>
        /// <param name="dbName">Name of Database.</param>
        /// <returns>Path to database.</returns>
        public string GetDBPath (string dbName)
        {
            List<cJData.icDBInfo> sources = new List<cJData.icDBInfo>();
            sources.AddRange(this.m_ProgramData.BibleDatabases);
            sources.AddRange(this.m_ProgramData.OtherDatabases);
            sources.AddRange(this.m_ProgramData.ReferenceDatabases);

            foreach (cJData.icDBInfo dbi in sources)
            {
                if (dbi.Name.Equals(dbName))
                {
                    return Common.DATA_FOLDER + dbi.Path;
                }
            }
            return null;
        }

        /// <summary>
        /// Gets the Name to the given datbase..
        /// </summary>
        /// <param name="dbName">Path to Database.</param>
        /// <returns>Name of database.</returns>
        public string GetDBName (string dbPath)
        {
            List<cJData.icDBInfo> sources = new List<cJData.icDBInfo>();
            sources.AddRange(this.m_ProgramData.BibleDatabases);
            sources.AddRange(this.m_ProgramData.OtherDatabases);
            sources.AddRange(this.m_ProgramData.ReferenceDatabases);

            foreach (cJData.icDBInfo dbi in sources)
            {
                if (Common.DATA_FOLDER + dbi.Path == dbPath)
                {
                    return dbi.Name;
                }
            }
            return null;
        }

        /// <summary>
        /// Gets an Internal Image...
        /// </summary>
        /// <param name="imageName">Name of Image to Get.</param>
        /// <returns>Image.</returns>
        public Image GetInternalImage (string imageName)
        {
            System.Reflection.Assembly assem;
            assem = this.GetType().Assembly;
            System.Resources.ResourceManager mngr = new System.Resources.ResourceManager("Jonathan.InternalImages", assem);
            Image img = (Image)mngr.GetObject(imageName);
            return img;
        }

        /// <summary>
        /// Occurs when the Tab Panel is Double Clicked...
        /// </summary>
        /// <param name="tabberGroup">Group for Panel that is double Clicked.</param>
        /// <param name="e">MouseEventArgs</param>
        void m_Tabber_TabPanelDoubleClick (TabberGroup tabberGroup, MouseEventArgs e)
        {
            this.m_Tabber.AddTab(new ctrlReader(this, this.m_ProgramData.DefaultBible, this.DefaultBibleFile), tabberGroup);
        }

        #endregion

        #region -= Book Marks =-

        /// <summary>
        /// Adds the given book mark...
        /// </summary>
        /// <param name="bmInfo">Info for book mark.</param>
        public void AddBookMark (string bmInfo)
        {
            string[] parsedInfo = bmInfo.Split('|');
            cPassage bm = new cPassage(parsedInfo[0], parsedInfo[1], parsedInfo[2], parsedInfo[3]);
            this.m_ProgramData.BookMarks.Add(bm);
            this.LoadBookMarks();
        }

        /// <summary>
        /// Removes the given book mark from the list...
        /// </summary>
        /// <param name="bm">Book Mark to Remove...</param>
        public void RemoveBookMark (cPassage bm)
        {
            if (MessageBox.Show(this, "Do you really want to delete the Book Mark for " + bm.ToString() + "?", "Jonathan",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                this.m_ProgramData.BookMarks.Remove(bm);
                this.LoadBookMarks();
            }
        }

        #endregion

        /// <summary>
        /// Gets the title of the abbreveation of other books...
        /// </summary>
        /// <param name="book">Book abbreveation</param>
        /// <returns>Full Book Name</returns>
        /*public static string GetOtherBook (string book)
        {
            foreach (cJData.icDBInfo dbI in this.m_ProgramData.OtherDatabases)
            {
                Database db = new Database(dbI.Path);
                Query qBookList = new Query(QueryType.SELECT, Common.TABLE_BOOK_LIST);
                qBookList.SELECT("*");
                db.RunQuery(qBookList);

                for (int a = 0; a < qBookList.RowsReturned; a++)
                {
                    string book = "";
                    string[] spBook = qBookList.Results.GetFieldString(0, a).Split(' ');
                    foreach (string b in spBook)
                    {
                        if (Char.IsLetter(b[0]))
                            book += b[0].ToString().ToUpper();
                    }
                }
            }
        }*/
    }
}